import { NextResponse } from 'next/server'; import { getCurrentUser } from '@/lib/auth/session'; import { getCollectionDetail } from '@/lib/account/queries'; import { toCsv } from '@/lib/account/portfolio'; export const dynamic = 'force-dynamic'; const COLUMNS = ['item_id', 'asset_id', 'asset_slug', 'title', 'category', 'variant', 'grader', 'grade', 'cert', 'serial', 'quantity', 'acquired_at', 'purchase_price', 'currency', 'purchase_price_usd', 'source', 'condition', 'value_usd', 'value_source', 'confidence', 'gain_usd', 'gain_pct', 'tags', 'notes']; export async function GET(req: Request, ctx: { params: Promise<{ id: string }> }) { const u = await getCurrentUser(); if (!u) return NextResponse.json({ error: 'unauthorized' }, { status: 401 }); const { id } = await ctx.params; const detail = await getCollectionDetail(u.id, id); if (!detail) return NextResponse.json({ error: 'not found' }, { status: 404 }); const format = new URL(req.url).searchParams.get('format') ?? 'csv'; const rows = detail.summary.items.map((i) => { const src = detail.items.find((x) => x.id === i.id)!; return { item_id: i.id, asset_id: i.assetId, asset_slug: src.assetSlug, title: i.title, category: i.categorySlug, variant: src.variantLabel, grader: i.grader, grade: i.grade, cert: src.certificationNumber, serial: src.serial, quantity: i.quantity, acquired_at: i.acquiredAt, purchase_price: src.purchasePriceNative, currency: src.acquiredCurrency, purchase_price_usd: i.purchasePriceUsd, source: src.source, condition: src.condition, value_usd: i.valueUsd, value_source: i.valueSource, confidence: i.confidence, gain_usd: i.gainUsd, gain_pct: i.gainPct, tags: src.tags.join('|'), notes: src.notes, }; }); const stamp = new Date().toISOString().slice(0, 10); if (format === 'json') { return new NextResponse(JSON.stringify({ collection: detail.collection.name, exportedAt: new Date().toISOString(), summary: { valueUsd: detail.summary.valueUsd, costBasisUsd: detail.summary.costBasisUsd, gainUsd: detail.summary.gainUsd, returnPct: detail.summary.returnPct, items: detail.summary.itemCount }, items: rows }, null, 2), { headers: { 'content-type': 'application/json', 'content-disposition': `attachment; filename="rareindex-${detail.collection.publicSlug ?? id}-${stamp}.json"` } }); } return new NextResponse(toCsv(rows, COLUMNS), { headers: { 'content-type': 'text/csv; charset=utf-8', 'content-disposition': `attachment; filename="rareindex-${detail.collection.publicSlug ?? id}-${stamp}.csv"` } }); }